/*
 * Copyright 2010 Alessandro Bellucci
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.soupframework.gwt.designerpanel.demos.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.ToggleButton;

public class ToggleButtonGroup implements ClickHandler, HasSelectionHandlers<ToggleButton> {

	private List<ToggleButton> toggleButtons = new ArrayList<ToggleButton>();

	private ToggleButton activeButton;

	/**
	 * Manager responsible for adding handlers to event sources and firing those
	 * handlers on passed in events.
	 */
	private HandlerManager handlerManager;

	public ToggleButtonGroup() {
	}

	public void add(ToggleButton toggleButton) {
		this.toggleButtons.add(toggleButton);
		toggleButton.addClickHandler(this);
	}

	public ToggleButton getActiveButton() {
		return this.activeButton;
	}

	public List<ToggleButton> getToggleButtons() {
		return this.toggleButtons;
	}

	public void clearSelection() {
		if(this.activeButton != null) {
			this.activeButton.setDown(false);
			this.activeButton = null;
			SelectionEvent.fire(this, this.activeButton);
		}
	}

	@Override
	public void onClick(ClickEvent event) {
		ToggleButton toggleButton = (ToggleButton)event.getSource();
		if(toggleButton.isDown()) {
			this.activeButton = toggleButton;
			for(ToggleButton tb : this.toggleButtons) {
				if(tb != toggleButton) {
					tb.setDown(false);
				}
			}
		}
		else {
			this.activeButton = null;
		}

		SelectionEvent.fire(this, this.activeButton);
	}

	/**
	* Ensures the existence of the handler manager.
	*
	* @return the handler manager
	*/
	HandlerManager ensureHandlers() {
		return handlerManager == null ? handlerManager = new HandlerManager(this) : handlerManager;
	}

	/**
	* Adds an handler for events.
	*
	* @param <H> the type of handler to add
	* @param type the event type
	* @param handler the handler
	* @return {@link HandlerRegistration} used to remove the handler
	*/
	protected final <H extends EventHandler> HandlerRegistration addHandler(final H handler, GwtEvent.Type<H> type) {
		return ensureHandlers().addHandler(type, handler);
	}

	@Override
	public void fireEvent(GwtEvent<?> event) {
		if(handlerManager != null) {
			handlerManager.fireEvent(event);
		}
	}

	@Override
	public HandlerRegistration addSelectionHandler(SelectionHandler<ToggleButton> handler) {
		return addHandler(handler, SelectionEvent.getType());
	}
}
